package com.ruoyi.riskrule.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.service.*;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.enums.RspEnmu;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.extdata.common.config.RuleConfig;
import com.ruoyi.riskrule.config.common.RuleUtils;
import com.ruoyi.riskrule.constants.Constants;
import com.ruoyi.riskrule.mapper.CustomerCreditReportMapper;
import com.ruoyi.riskrule.service.ICreditFieldService;
import com.ruoyi.riskrule.service.ILoanFieldService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Configuration
@AllArgsConstructor
public class RaiseLimitParamsLoader {

    private RuleConfig ruleConfig;

    private ILoanOrderService loanOrderService;

    private ILoanIouService iLoanIouService;

    private ICreditApplyService creditApplyService;

    private IRealNameAuthService realNameAuthService;

    private ICreditFieldService creditService;

    private ILoanFieldService loanService;

    private ICustBankCardService iCustBankCardService;

    private CustomerCreditReportMapper customerCreditReportMapper;

    private IAppUserService appUserService;

    private IIncreasedLimitLogService increasedLimitLogService;

    private ICreditAccountService creditAccountService;

    private ICustomerInfoService customerInfoService;

    private ILoanIouDeferredService loanIouDeferredService;

    private IProductDeferredInfoService productDeferredInfoService;

    //规则参数加工
    @SneakyThrows
    public RuleIn initRuleInParam(String loanSerialNo, String customerNo) {
        RuleIn ruleIn = new RuleIn();
        ruleIn.setEntryId(IdUtils.reqId());
        ruleIn.setProductCode(ruleConfig.getProductCode());
        ruleIn.setRunType(ruleConfig.getRunType());
        ruleIn.setLoanSerialNo(loanSerialNo);
        ruleIn.setOperType("5");

        ruleIn.setWorkflowCode(RuleConfig.RULE_WORK_FLOW_CODE_LIMIT_ADJUST1);

        //当笔订单的总延期次数
        Integer currentDeferredCnt = getcurrentDeferredCnt(loanSerialNo);
        ruleIn.setCurrentdeferredcnt(currentDeferredCnt == 0 ? "-1" : currentDeferredCnt + "");

        //当笔订单的总延期天数
        Integer days = getCurrentDeferredDays(loanSerialNo);
        ruleIn.setCurrentdeferreddays(days == 0 ? "-1" : days + "");

        //当前提现距该客户最近一次提现成功的时间
        String whdwsjcha2 = getwhdwsjcha2(customerNo);
        ruleIn.setWhdwsjcha2(whdwsjcha2);
        //实名信息
        RealNameAuth realName = getRealAuthByCustNo(customerNo);
        //授信订单
        CreditApply apply = getCreditApplyByCustNo(customerNo);
        //提现订单
        LoanIou loanIou = getLoanOrderBySerialNo(loanSerialNo, customerNo);
        //授信账户
        CreditAccount creditAccount = getCreditAccount(customerNo);
        //AppUser
        AppUser user = getUser(realName.getUserId());
        //客户信息
        CustomerInfo custmerInfo = getCustmerInfo(customerNo);

        ruleIn.setModellevel(custmerInfo.getModelLevel());

        ruleIn.setMobile(user.getPhone());
        ruleIn.setCustNo(realName.getUserId());
        // 当笔订单的应收利息
        String currentinterest = loanIouDeferredService.getcurrentinterest(loanSerialNo);
        ruleIn.setCurrentinterest(currentinterest);
//        ruleIn.setCurrentinterest(loanIou.getLoanInterest().toString());
        // 当笔订单的应收服务费
        String currentservicefee = loanIouDeferredService.getloanIouDeferredService(loanSerialNo);
        ruleIn.setCurrentservicefee(currentservicefee);
//        ruleIn.setCurrentservicefee(loanIou.getServiceFee().toString());
        // 当笔罚息
        ruleIn.setCurrentlatefee(loanIou.getLateFee().toString());

        ruleIn.setBvnNumber(realName.getBvnAccount());
        ruleIn.setUserName(realName.getFirstName() + " " + realName.getMiddleName() + " " + realName.getLastName());

        LoanOrder loanOrderq = new LoanOrder();
        loanOrderq.setCustNo(customerNo);
        List<LoanOrder> loanOrderList = loanOrderService.selectLoanOrderList(loanOrderq);

        //当前申请人申请交易订单数
        ruleIn.setTradeOrders(loanOrderList.size() + "");

        //取消订单？
        int traderejects = 0;
        int tradeaccepts = 0;
        for (LoanOrder res : loanOrderList) {
            //当前申请人交易申请拒绝订单数
            boolean traderejectsflag = 0 == res.getLoanStatus();
            if (traderejectsflag) {
                traderejects++;
            }
            //当前申请人交易申请通过订单数
            boolean tradeacceptsflag = res.getLoanStatus() == 1 || res.getLoanStatus() == 4 || res.getLoanStatus() == 5;
            if (tradeacceptsflag) {
                tradeaccepts++;
            }
        }
        ruleIn.setTradeRejects(traderejects + "");
        ruleIn.setTradeAccepts(tradeaccepts + "");

        //当前申请人最近一笔完成审批交易申请单的决策引擎审批结果
        LoanOrder approvedRecentResult = loanService.getApprovedRecentResult(loanOrderList.get(0).getCustNo());
        if (approvedRecentResult != null) {
            Integer loanStatus = approvedRecentResult.getLoanStatus();
            String str = "";
            if (8 == loanStatus) {
                str = "关闭";
            } else if (10 == loanStatus) {
                str = "取消";
            } else if (0 == loanStatus) {
                str = "拒绝";
            } else {
                str = "通过";
            }
            ruleIn.setTradeResults(str);
        }

        //该客户所有提现成功的次数下
        ruleIn.setWithdrawsucd(loanService.selectContractsByStatus(customerNo, null, null) + "");

        Integer[] statusArr = new Integer[2];
        statusArr[0] = 1;
        //当前申请人结清合同数
        ruleIn.setJieqinghetong(loanService.selectContractsByStatus(customerNo, statusArr, loanIou.getUpdateTime()) + "");
        //当前申请人未结清合同数
        statusArr[0] = 0;
        statusArr[1] = 2;
        ruleIn.setZaidaihetong(loanService.selectContractsByStatus(customerNo, statusArr, loanIou.getUpdateTime()) + "");

        //客户第一次解析成功不为空的州
        ruleIn.setFristcountrystate(creditService.getFristcountrystate(apply.getUserId()));

        //获取客户所有的借据
        List<LoanIou> activeLoanList = loanService.getLoanIouByCustNo(customerNo, loanIou.getUpdateTime());
        BigDecimal zaidaibenjin = new BigDecimal(0);
        BigDecimal jieqingbenjin = new BigDecimal(0);
        BigDecimal jieqinglixi = new BigDecimal(0);
        BigDecimal jieqingfuwufei = new BigDecimal(0);
        BigDecimal jieqingfaxi = new BigDecimal(0);
        BigDecimal zaidaibenjin2 = BigDecimal.ZERO;

        for (LoanIou iou : activeLoanList) {

            if (iou.getIouStatus() == 0 || iou.getIouStatus() == 2) {
                zaidaibenjin2 = zaidaibenjin2.add(iou.getLoanPrincipal());
                zaidaibenjin = zaidaibenjin.add(iou.getLoanPrincipal().subtract(iou.getRepaidPrincipal()));
            }

            jieqingbenjin = jieqingbenjin.add(iou.getRepaidPrincipal());
            jieqinglixi = jieqinglixi.add(iou.getRepaidInterest());
            jieqingfuwufei = jieqingfuwufei.add(iou.getRepaidServiceFee());
            jieqingfaxi = jieqingfaxi.add(iou.getRepaidLateFee());
        }
        BigDecimal ss = StringUtils.isBlank(creditAccount.getCreditLine().toString()) ? BigDecimal.ZERO : new BigDecimal(creditAccount.getCreditLine().toString()).subtract(zaidaibenjin2);
        String s = bigDecimalToString(ss);
        ruleIn.setRestofamt(s);
        //在贷本金
        ruleIn.setZaidaibenjin(bigDecimalToString(zaidaibenjin));
        //当前申请人结清本金
        ruleIn.setJieqingbenjin(bigDecimalToString(jieqingbenjin));
//        ruleIn.setJieqinglixi(bigDecimalToString(jieqinglixi));
//        ruleIn.setJieqingfuwufei(bigDecimalToString(jieqingfuwufei));
        //当前申请人结清罚息
        ruleIn.setJieqingfaxi(bigDecimalToString(jieqingfaxi));


        //当前提现申请距该客户最近一次提现申请的时间
        Integer loanLastTimeInterval = loanService.getLastTimeInterval(customerNo);
        ruleIn.setWhdwsjcha1(loanLastTimeInterval == null ? "0" : loanLastTimeInterval + "");

        //当前提现申请距该客户最近的在贷账单日的时间，可为0
        Integer lastTimeIntervalOfIou = loanService.getLastTimeIntervalOfIou(customerNo);
        ruleIn.setZdzhangdanricha(lastTimeIntervalOfIou == null || lastTimeIntervalOfIou < 0 ? "-1" : lastTimeIntervalOfIou + "");

        //最近60天提现申请次数
        int cntApply60Days = creditService.getCntApply60Days(realName.getUserId());
        ruleIn.setCntApply60Days(cntApply60Days + "");

        //min_duedate
        LoanIou loanIouQ = new LoanIou();
        loanIouQ.setCustNo(customerNo);
        loanIouQ.setState(BizConstants.BIZ_STATUS_1);
        loanIouQ.setIouStatus(0);
//        List<LoanIou> loanIouList = iLoanIouService.selectLoanIouList(loanIouQ);
//        if (loanIouList.size() > 0) {
//            Collections.sort(loanIouList, Comparator.comparing(o -> DateUtils.parseDate(o.getRepayDate())));
//            //Collections.sort(loanIouList, Comparator.comparing(BaseEntity::getCreateTime));
//            ruleIn.setMinDuedate(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", DateUtils.parseDate(loanIouList.get(0).getRepayDate())));
//        }else {
//            ruleIn.setMinDuedate("2000-01-01 00:00:00");
//        }

        //绑定的银行卡
        CustBankCard custBankCard = new CustBankCard();
        custBankCard.setState(UserConstants.BUSINESS_NORMAL);
        custBankCard.setCustNo(customerNo);
        List<CustBankCard> custBankCards = iCustBankCardService.selectCustBankCardList(custBankCard);
        ruleIn.setBindcardno(custBankCards.size() + "");

        Date data = customerCreditReportMapper.getCustomerCreditReportData(realName.getUserId());
        ruleIn.setLasttimereport(null != data ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(data) : Constants.DEFAULT_TIME);

        ruleIn.setGender(StringUtils.equalsAny(realName.getGender(), "0", "M") ? "M" : "F");
        ruleIn.setReligion(apply.getReligion());
        ruleIn.setFristlanguage(apply.getNativeLanguage());
        ruleIn.setNumofchildren(null != apply.getChildrenNumber() ? String.valueOf(apply.getChildrenNumber()) : null);
        ruleIn.setSalarydate(apply.getSalaryDate());

        try {
            ruleIn.setEntrytime(StringUtils.isNotEmpty(apply.getResumptionDate()) ?
                    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new SimpleDateFormat("dd-MM-yyyy").parse(apply.getResumptionDate())) : Constants.DEFAULT_TIME);
        } catch (ParseException e) {
            log.error("反人类日期转化失败:{}", e.getMessage());
        }

        //settletype 当前结清产品类型
        ruleIn.setSettletype(loanIou.getPeriodNum() + "");

        int overdueDay = this.dayCompare(loanIou.getIsDeferred() == 0 ? loanIou.getRepayDate() : loanIou.getDeferredRepayDate());
        if (overdueDay >= 0) {
            ruleIn.setSettleodnum(overdueDay + "");
        }
        ruleIn.setSettledate(overdueDay < 0 ? "0" : overdueDay == 0 ? "1" : "2");

        //usedrate	（在贷本金+此次提现金额）/当前总额度
        BigDecimal loanQuota = creditAccount.getLoanQuota().add(loanIou.getLoanAmt());
        ruleIn.setUsedrate(loanQuota.divide(creditAccount.getCreditLine(), BigDecimal.ROUND_HALF_UP) + "");

        ruleIn.setRecFlag(UserConstants.BUSINESS_NOT_NORMAL);
        ruleIn.setState(UserConstants.BUSINESS_NORMAL);
        //风控要求 部分字段格式化
        return RuleUtils.afterFormat(ruleIn);
    }


    //天数比较
    private int dayCompare(String repayDate) {
        Calendar aCalendar = Calendar.getInstance();
        try {
            aCalendar.setTime(new SimpleDateFormat("yyyy/MM/dd").parse(repayDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
        aCalendar.setTime(new Date());
        int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
        return day2 - day1;
    }

    private String getwhdwsjcha2(String custNo) {
        return iLoanIouService.getwhdwsjcha2(custNo);
    }

    private Integer getCurrentDeferredDays(String loanSerialNo) {
        BigDecimal days = new BigDecimal(0);
        List<LoanIouDeferred> loanList = loanIouDeferredService.list(new QueryWrapper<LoanIouDeferred>().eq("loan_serial_no", loanSerialNo).eq("state", 1));
        if (loanList.size() > 0) {
            for (LoanIouDeferred loanIouDeferred : loanList) {
                ProductDeferredInfo productDeferredInfo = productDeferredInfoService.getOne(new QueryWrapper<ProductDeferredInfo>().eq("id", loanIouDeferred.getProductDeferredId()).eq("state", 1));
                Integer multiply = productDeferredInfo.getNumDeferredDay();
                days = days.add(BigDecimal.valueOf(multiply));
            }
        }
        return Integer.valueOf(days.toString());
    }

    private Integer getcurrentDeferredCnt(String loanSerialNo) {
        return loanIouDeferredService.getCurrentDeferredCnt(loanSerialNo);
    }


    public CreditAccount getCreditAccount(String customerNo) {

        CreditAccount creditAccount = new CreditAccount();
        creditAccount.setCustNo(customerNo);
        creditAccount.setState(UserConstants.BUSINESS_NORMAL);
        List<CreditAccount> selectCreditAccountList = creditAccountService.selectCreditAccountList(creditAccount);
        if (CollectionUtils.isEmpty(selectCreditAccountList)) {
            throw new BusinessException(RspEnmu.NO_RECORD);
        }
        return selectCreditAccountList.get(0);
    }


    private CustomerInfo getCustmerInfo(String customerNo) {

        CustomerInfo customerInfo = new CustomerInfo();
        customerInfo.setCustNo(customerNo);
        List<CustomerInfo> customerInfos = customerInfoService.selectCustomerInfoList(customerInfo);
        if (CollectionUtils.isEmpty(customerInfos)) {
            throw new BusinessException(RspEnmu.NO_RECORD);
        }
        return customerInfos.get(0);
    }

    private LoanIou getLoanOrderBySerialNo(String loanSerialNo, String customerNo) {
        LoanIou loanIou = new LoanIou();
        loanIou.setCustNo(customerNo);
        loanIou.setLoanSerialNo(loanSerialNo);
        List<LoanIou> loanIouList = iLoanIouService.selectLoanIouList(loanIou);
        if (CollectionUtils.isEmpty(loanIouList)) {
            throw new BusinessException(RspEnmu.NO_RECORD);
        }
        return loanIouList.get(0);
    }


    public String bigDecimalToString(BigDecimal bigDecimal) {
        return bigDecimal == null ? "0.000" : bigDecimal + "";
    }

    private RealNameAuth getRealAuthByCustNo(String custNo) {
        //实名认证
        RealNameAuth auth = new RealNameAuth();
        auth.setCustNo(custNo);
        List<RealNameAuth> realNameAuthList = realNameAuthService.selectRealNameAuthList(auth);
        if (realNameAuthList.size() == 0) {
            throw new BusinessException(RspEnmu.USERID_IS_EMPTY);
        }
        return realNameAuthList.get(0);
    }


    private AppUser getUser(String userId) {
        AppUser appUser = new AppUser();
        appUser.setUserUuid(userId);
        List<AppUser> appUsers = appUserService.selectAppUserList(appUser);
        if (appUsers.size() == 0) {
            throw new BusinessException(RspEnmu.USERID_IS_EMPTY);
        }
        return appUsers.get(0);
    }

    private CreditApply getCreditApplyByCustNo(String custmerNo) {
        CreditApply creditApply = new CreditApply();
        creditApply.setCustNo(custmerNo);
        creditApply.setApplyStatus(1);
        List<CreditApply> creditApplyList = creditApplyService.selectCreditApplyList(creditApply);
        if (CollectionUtils.isEmpty(creditApplyList)) {
            throw new BusinessException(RspEnmu.NO_RECORD);
        }
        return creditApplyList.get(0);
    }


}
